package com.cff.springbootwork.oauth.auth;

import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.client.BaseClientDetails;
import org.springframework.security.oauth2.provider.client.InMemoryClientDetailsService;
import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;

import com.cff.springbootwork.oauth.provider.DefaultPasswordEncoder;

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

	private static String REALM = "MY_OAUTH_REALM";

	@Autowired
	private AuthenticationManager authenticationManager;
	
	@Autowired
	DefaultPasswordEncoder defaultPasswordEncoder;

	@Autowired
	@Qualifier("authorizationCodeServices")
	private AuthorizationCodeServices authorizationCodeServices;

	/**
	 * 可以在这里将客户端数据替换成数据库配置。
	 * 
	 * @return
	 */
	@Bean
	public ClientDetailsService clientDetailsService() {
		InMemoryClientDetailsService inMemoryClientDetailsService = new InMemoryClientDetailsService();
		BaseClientDetails baseClientDetails = new BaseClientDetails();
		baseClientDetails.setClientId("MwonYjDKBuPtLLlK");
		baseClientDetails.setClientSecret(defaultPasswordEncoder.encode("123456"));
		baseClientDetails.setAccessTokenValiditySeconds(120);
		baseClientDetails.setRefreshTokenValiditySeconds(600);
		
		Set<String> salesWords = new HashSet<String>() {{
			add("http://www.pomit.cn");
		}};
		baseClientDetails.setRegisteredRedirectUri(salesWords);
		List<String> scope = Arrays.asList("read", "write", "trust");
		baseClientDetails.setScope(scope);

		List<String> authorizedGrantTypes = Arrays.asList("authorization_code", "refresh_token");
		baseClientDetails.setAuthorizedGrantTypes(authorizedGrantTypes);

		Map<String, ClientDetails> clientDetailsStore = new HashMap<>();
		clientDetailsStore.put("MwonYjDKBuPtLLlK", baseClientDetails);
		inMemoryClientDetailsService.setClientDetailsStore(clientDetailsStore);

		return inMemoryClientDetailsService;
	}

	@Override
	public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
		clients.withClientDetails(clientDetailsService());
	}

	@Override
	public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
		endpoints.authenticationManager(authenticationManager);
		endpoints.authorizationCodeServices(authorizationCodeServices);
	}

	@Override
	public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
		oauthServer.allowFormAuthenticationForClients();
		oauthServer.realm(REALM + "/client");
	}
}
